#include "FieldValuesContainer.h"
#include "ScriptRuntime/Type/GSharpFieldProperty.h"
CGSharpFieldValuesContainer::CGSharpFieldValuesContainer(
    TVector<CGSharpFieldProperty *> InFields
    ,uint32_t InStartFieldIndex
    )
{
    Fields = InFields;
    StartFieldIndex = InStartFieldIndex;

    Values.Reserve(Fields.Num());

    for (auto Field : Fields)
    {
        auto DefaultValue = Field->GetDefaultValue();
        if(DefaultValue.HasValue())
        {
            Values.Emplace(DefaultValue.GetValue().ToAny());
        }
        else
        {
            Values.Emplace(Field->GetType().BasicType,Field->GetType().BasicType->CreateInstance());
        }
    }
}  

CGSharpFieldValuesContainer::~CGSharpFieldValuesContainer()
{
    // for(uint32_t i=0;i<Fields.Num();i++)
    // {
    //     Fields[i]->GetType()->EraseInstance(Values[i]);
    // }
}

void CGSharpFieldValuesContainer::SetValue(uint32_t InIndex, CAny &&InValue)
{
    uint32_t Index = InIndex - StartFieldIndex;
    assert(InValue.GetType()->IsForceConvertableTo(Fields[Index]->GetType().BasicType));

    //1.erase old value
    Fields[Index]->GetType().BasicType->EraseInstance(Values[Index].GetPointer());

    //2. copy new value
    Fields[Index]->GetType().BasicType->CloneInstance(
        InValue.GetPointer()
        ,Values[Index].GetPointer()
    );
}

void CGSharpFieldValuesContainer::SetValue(uint32_t InIndex, const CAny &InValue)
{
    assert(InIndex>=StartFieldIndex && InIndex<StartFieldIndex+Fields.Num());
    
    uint32_t Index = InIndex - StartFieldIndex;
    assert(InValue.GetType()->IsForceConvertableTo(Fields[Index]->GetType().BasicType));
    
    //1.erase old value
    Fields[Index]->GetType().BasicType->EraseInstance(Values[Index].GetPointer());

    //2. copy new value
    Fields[Index]->GetType().BasicType->CloneInstance(
        InValue.GetPointer()
        ,Values[Index].GetPointer()
    );
}

const CAny& CGSharpFieldValuesContainer::GetValue(uint32_t InIndex) const
{
    uint32_t Index = InIndex - StartFieldIndex;
    return Values[Index];
}

void *CGSharpFieldValuesContainer::GetValuePointer(uint32_t InIndex) const
{
    uint32_t Index = InIndex - StartFieldIndex;
    return Values[Index].GetPointer();
}

void CGSharpFieldValuesContainer::ResetValues()
{
    for (uint32_t i = 0; i < Fields.Num(); i++)
    {
        Fields[i]->GetType().BasicType->ResetAllocated(Values[i].GetPointer());
    }
}
